`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: CBICR, Tsinghua Univ.
// Engineer: Hongyi Li
// 
// Create Date: 2025/01/07 17:11:45
// Design Name: 
// Module Name: Look-Ahead Generator
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module LkAheadGen
#(
    parameter DataWidth = 'd32,
    parameter LkAheadWidth = 'd14
)(
    input                     clk,
    input                     rst_n,
    input  [DataWidth   -1:0] i_head_e,
    input  [DataWidth   -1:0] i_head_w,
    input  [DataWidth   -1:0] i_head_n,
    input  [DataWidth   -1:0] i_head_s,
    input  [DataWidth   -1:0] i_head_l,
    input  [25          -1:0] i_alloc_mat,  // i_dir -> o_dir
    output [LkAheadWidth-1:0] o_lookahead_e,
    output [LkAheadWidth-1:0] o_lookahead_w,
    output [LkAheadWidth-1:0] o_lookahead_n,
    output [LkAheadWidth-1:0] o_lookahead_s,
    output [LkAheadWidth-1:0] o_lookahead_l
);

reg   [LkAheadWidth-1:0]  reg_lookahead_e, reg_lookahead_w;
reg   [LkAheadWidth-1:0]  reg_lookahead_n, reg_lookahead_s, reg_lookahead_l;

assign o_lookahead_e = reg_lookahead_e;
assign o_lookahead_w = reg_lookahead_w;
assign o_lookahead_n = reg_lookahead_n;
assign o_lookahead_s = reg_lookahead_s;
assign o_lookahead_l = reg_lookahead_l;

always @(posedge clk) begin
    if (~rst_n) begin
        reg_lookahead_e <= 0;
        reg_lookahead_w <= 0;
        reg_lookahead_n <= 0;
        reg_lookahead_s <= 0;
        reg_lookahead_l <= 0;
    end else begin
        reg_lookahead_e <=  i_alloc_mat[0] ? {2'b00, i_head_e[19:8]} :
                            i_alloc_mat[1] ? {2'b00, i_head_w[19:8]} :
                            i_alloc_mat[2] ? {2'b00, i_head_n[19:8]} :
                            i_alloc_mat[3] ? {2'b00, i_head_s[19:8]} :
                            i_alloc_mat[4] ? {2'b00, i_head_l[19:8]} :
                            0;
        reg_lookahead_w <=  i_alloc_mat[5] ? {2'b00, i_head_e[19:8]} :
                            i_alloc_mat[6] ? {2'b00, i_head_w[19:8]} :
                            i_alloc_mat[7] ? {2'b00, i_head_n[19:8]} :
                            i_alloc_mat[8] ? {2'b00, i_head_s[19:8]} :
                            i_alloc_mat[9] ? {2'b00, i_head_l[19:8]} :
                            0;
        reg_lookahead_n <=  i_alloc_mat[10] ? {2'b00, i_head_e[19:8]} :
                            i_alloc_mat[11] ? {2'b00, i_head_w[19:8]} :
                            i_alloc_mat[12] ? {2'b00, i_head_n[19:8]} :
                            i_alloc_mat[13] ? {2'b00, i_head_s[19:8]} :
                            i_alloc_mat[14] ? {2'b00, i_head_l[19:8]} :
                            0;
        reg_lookahead_s <=  i_alloc_mat[15] ? {2'b00, i_head_e[19:8]} :
                            i_alloc_mat[16] ? {2'b00, i_head_w[19:8]} :
                            i_alloc_mat[17] ? {2'b00, i_head_n[19:8]} :
                            i_alloc_mat[18] ? {2'b00, i_head_s[19:8]} :
                            i_alloc_mat[19] ? {2'b00, i_head_l[19:8]} :
                            0;
        reg_lookahead_l <=  i_alloc_mat[20] ? {2'b00, i_head_e[19:8]} :
                            i_alloc_mat[21] ? {2'b00, i_head_w[19:8]} :
                            i_alloc_mat[22] ? {2'b00, i_head_n[19:8]} :
                            i_alloc_mat[23] ? {2'b00, i_head_s[19:8]} :
                            i_alloc_mat[24] ? {2'b00, i_head_l[19:8]} :
                            0;
    end
end

endmodule